<template>
  <div id="viewQuestionView">
    <a-row :gutter="[24, 24]">
      <a-col :md="12" :xs="24">
        <a-tabs default-active-key="question">
          <a-tab-pane key="question" title="题目">
            <a-card v-if="question" :title="question.title">
              <a-descriptions
                title="判题条件"
                :column="{ xs: 1, md: 2, lg: 3 }"
              >
                <a-descriptions-item label="时间限制">
                  {{ question.timeLimit ?? 0 }}
                  MS
                </a-descriptions-item>
                <a-descriptions-item label="内存限制">
                  {{ question.memoryLimit ?? 0 }}
                  KB
                </a-descriptions-item>
              </a-descriptions>
              <MdViewer :value="question.content || '暂无题目内容'" />
              <template #extra>
                <a-space wrap>
                  <a-tag
                    v-for="(tag, index) of question.tags"
                    :key="index"
                    color="green"
                    >{{ tag }}
                  </a-tag>
                </a-space>
              </template>
            </a-card>
          </a-tab-pane>
          <a-tab-pane key="about" title="系统说明">
            <a-card :title="'用户代码文件执行环境说明'">
              <MdViewer :value="aboutValue" />
            </a-card>
          </a-tab-pane>
          <a-tab-pane key="resultAbout" title="判题结果说明">
            <a-card :title="'判题结果说明'">
              <MdViewer :value="resultValue" />
            </a-card>
          </a-tab-pane>
        </a-tabs>
      </a-col>
      <a-col :md="12" :xs="24">
        <a-form :model="form" layout="inline">
          <a-form-item
            field="language"
            label="编程语言 : Bash"
            style="min-width: 240px"
          >
          </a-form-item>
        </a-form>
        <CodeEditor
          :key="props.id"
          :value="form.code as string"
          :handle-change="changeCode"
          :id="BigInt(props.id)"
          :readonly="false"
          :code="''"
        />
        <a-divider :size="0" />
        <a-space>
          <a-button type="primary" style="min-width: 200px" @click="doSubmit">
            提交代码
          </a-button>
          <a-button type="primary" style="min-width: 200px" @click="doNext">
            下一题
          </a-button>
          <a-button type="primary" style="min-width: 200px" @click="doBack">
            返回
          </a-button>
        </a-space>
      </a-col>
    </a-row>
  </div>
  <a-modal
    v-model:visible="visible"
    @ok="handleOk"
    @cancel="handleCancel"
    draggable
    :esc-to-close="false"
    :mask-closable="false"
  >
    <template #title> {{ modalTitle }}</template>
    <div v-if="modalTitle.startsWith('正在判题中')" style="text-align: center">
      关闭此窗口不影响判题
    </div>
    <div v-if="judgeTime">时间消耗: {{ judgeTime }} MS</div>
    <div v-if="judgeMemory">内存消耗: {{ judgeMemory }} KB</div>
  </a-modal>
</template>

<script setup lang="ts">
import { defineProps, onMounted, ref, withDefaults } from "vue";
import {
  QuestionControllerService,
  QuestionSubmitAddRequest,
  QuestionSubmitControllerService,
  QuestionVO,
} from "../../../api";
import message from "@arco-design/web-vue/es/message";
import CodeEditor from "@/components/CodeEditor.vue";
import MdViewer from "@/components/MdViewer.vue";
import { watch } from "vue";

const router = useRouter();
import { useRouter } from "vue-router";

interface Props {
  id: string;
}

const props = withDefaults(defineProps<Props>(), {
  id: () => "",
});

const question = ref<QuestionVO>();
//const question = ref<QuestionVO | null>(null);
const visible = ref(false);
const modalTitle = ref("正在判题中");
const judgeTime = ref<number>();
const judgeMemory = ref<number>();
let timer: ReturnType<typeof setInterval>;
const pollTimer = ref<ReturnType<typeof setInterval>>();
const dotTimer = ref<ReturnType<typeof setInterval>>();
const aboutValue = `本系统执行用户代码文件使用的系统为：Alpine Linux v3.12.0

Alpine主页：https://alpinelinux.org/posts/Alpine-3.12.0-released.html

在线Alpine虚拟机：https://bellard.org/jslinux/vm.html?url=alpine-x86.cfg&mem=192
（可在此网址中验证程序有效性，点击左下角上传按钮可上传Bash脚本文件。）
`;
const resultValue = `Accepted：用户代码通过所有测试用例。

Wrong Answer：用户代码结果与预期结果不符。

Memory Limit Exceeded：执行用户代码消耗的内存超过题目的内存限制。

Time Limit Exceeded：执行用户代码消耗的时间超过题目的时间限制。

Waiting：用户代码正在判题中。

Dangerous Code：用户代码中含有可能危害系统的命令。

Runtime Error：执行用户代码时出现错误，建议在提供的在线Alpine虚拟机进行验证。

System Error：系统出现错误，请联系管理员。
`;
// 新增响应式变量
let elapsedTime = 0;
const handleOk = () => {
  visible.value = false;
  if (timer) {
    clearInterval(timer);
    modalTitle.value = "正在判题中";
    judgeTime.value = undefined;
    judgeMemory.value = undefined;
  }
};
const handleCancel = () => {
  visible.value = false;
  if (timer) {
    clearInterval(timer);
  }
  modalTitle.value = "正在判题中";
  judgeTime.value = undefined;
  judgeMemory.value = undefined;
};

// 修改后的 startTimer
const startTimer = (id: number) => {
  modalTitle.value = "正在判题中";
  let dotCount = 0;

  // 清理可能的旧定时器
  if (dotTimer.value) clearInterval(dotTimer.value);
  if (pollTimer.value) clearInterval(pollTimer.value);

  // 点动画定时器
  dotTimer.value = setInterval(() => {
    dotCount = (dotCount + 1) % 4;
    modalTitle.value = `正在判题中${".".repeat(dotCount)}`;
    judgeTime.value = judgeMemory.value = undefined;
  }, 500);

  // 轮询定时器
  pollTimer.value = setInterval(async () => {
    elapsedTime++;

    if (elapsedTime >= 600) {
      clearTimers();
      modalTitle.value = "判题超时";
      judgeTime.value = judgeMemory.value = undefined;
      return;
    }

    const res = await QuestionSubmitControllerService.getQuestionSubmitVoById(
      id
    );
    if (res.code === 0 && res.data?.judgeResult !== "Waiting") {
      clearTimers();
      modalTitle.value = res.data?.judgeResult ?? "系统忙...";
      judgeTime.value = res.data?.timeUsed ?? 0;
      judgeMemory.value = res.data?.memoryUsed ?? 0;
    }
  }, 1000);
};

// 修改后的清理方法
const clearTimers = () => {
  if (dotTimer.value) {
    clearInterval(dotTimer.value);
    dotTimer.value = undefined;
  }
  if (pollTimer.value) {
    clearInterval(pollTimer.value);
    pollTimer.value = undefined;
  }
  elapsedTime = 0;
};

const loadData = async () => {
  // eslint-disable-next-line
  const res = await QuestionControllerService.getQuestionVo(props.id as any);
  if (res.code === 0) {
    question.value = res.data;
  } else {
    message.error("加载失败，" + res.message);
  }
};

const form = ref<QuestionSubmitAddRequest>({
  code: "",
  questionId: Number(props.id),
});

/**
 * 提交代码
 */
const doSubmit = async () => {
  if (!question.value?.id) {
    return;
  }
  const res = await QuestionSubmitControllerService.submit(form.value);
  if (res.code === 0) {
    message.success("提交成功");
  } else {
    message.error("提交失败," + res.message);
    return;
  }
  visible.value = true;
  startTimer(res.data ?? 0);
};

/**
 * 下一道题
 */
const doNext = async () => {
  const res = await QuestionControllerService.getNextQuestionId(
    question.value?.id ?? 0
  );
  if (res.code !== 0) {
    message.error(res.message ?? "系统错误，请联系管理员!");
  } else {
    form.value.questionId = res.data ?? 0;
    await router.push({
      path: `/view/question/${res.data}`,
    });
  }
};

/**
 * 返回题目浏览
 */
const doBack = () => {
  router.push({
    path: `/question`,
  });
};

// 在 setup 中添加
watch(
  () => props.id,
  async (newId) => {
    form.value.questionId = Number(newId); // 更新 form 的 questionId
    await loadData();
  },
  { immediate: true }
);

/**
 * 页面加载时，请求数据
 */

onMounted(async () => {
  await loadData();
});

const changeCode = (value: string) => {
  form.value.code = value;
};
</script>

<style>
#viewQuestionView {
  max-width: 1400px;
  margin: 0 auto;
}
</style>
